package com.liuqi.openai.core.chat;

import com.liuqi.openai.core.shared.StreamOptions;
import java.util.List;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * openai api /chat/completions 的请求内容
 *
 * @author liuqi
 * @date 2025/7/18
 **/
@Getter
@Setter
@ToString
@Builder
public class ChatCompletionRequest {

    /**
     * ai 模型
     */
    private String model;

    /**
     * 消息
     */
    private List<Message> messages;

    /**
     * 是否流式输出回复
     */
    private Boolean stream;

    /**
     * 当启用流式输出时，可通过将本参数设置为{"include_usage": true}，在输出的最后一行显示所使用的Token数
     */
    private StreamOptions streamOptions;

    /**
     * 采样温度，控制模型生成文本的多样性。
     *
     * temperature越高，生成的文本更多样，反之，生成的文本更确定
     */
    private Float temperature;

    /**
     * 核采样的概率阈值，控制模型生成文本的多样性。
     *
     * top_p越高，生成的文本更多样。反之，生成的文本更确定。
     */
    private Float topP;

    /**
     * 生成过程中采样候选集的大小。例如，取值为50时，仅将单次生成中得分最高的50个Token组成随机采样的候选集。
     * 取值越大，生成的随机性越高；取值越小，生成的确定性越高。取值为None或当top_k大于100时，表示不启用top_k策略，此时仅有top_p策略生效。
     * 取值需要大于或等于0。
     */
    private Integer topK;

    /**
     * presencePenalty frequencyPenalty 控制模型生成文本时的内容重复度
     * 取值范围：[-2.0, 2.0]。正数会减少重复度，负数会增加重复度。
     *
     * 适用场景：
     * 较高的presence_penalty适用于要求多样性、趣味性或创造性的场景，如创意写作或头脑风暴。
     * 较低的presence_penalty适用于要求一致性或专业术语的场景，如技术文档或其他正式文档。
     */

    /**
     * 只要词汇出现过就惩罚, 不考虑重复次数，平等惩罚, 鼓励使用新词汇
     */
    private Float presencePenalty;

    /**
     * 基于词汇出现频率进行惩罚, 对重复出现的词惩罚更强, 减少高频重复词汇
     */
    private Float frequencyPenalty;

    /**
     * 本次请求返回的最大 Token 数
     */
    private Integer maxTokens;

    /**
     * 生成响应的个数，取值范围是1-4
     */
    private Integer n;

    /**
     * 启用思考模式
     */
    private Boolean enableThinking;

    /**
     * 思考过程的最大长度，在enable_thinking为true时生效
     */
    private Integer thinkingBudget;

    /**
     * 设置seed参数会使文本生成过程更具有确定性，通常用于使模型每次运行的结果一致
     */
    private Integer seed;

    /**
     * 当模型生成的文本即将包含指定的字符串或token_id时，将自动停止生成
     */
    private List<String> stop;

    /**
     * 可供模型调用的工具数组
     */
    private List<Tool> tools;

    /**
     * none、auto、object
     */
    private Object toolChoice;

    /**
     * 是否开启并行工具调用。参数为true时开启，为false时不开启。
     */
    private Boolean parallelToolCalls;

    /**
     * 是否启用互联网搜索
     */
    private Boolean enableSearch;

    /**
     * 互联网搜索参数  {@link #enableSearch} = true 时生效
     */
    private Map<String, Object> searchOptions;

}
